//
// index.js
// vue3-element-admin
//
// Created by 区区电脑 on 2023/04/10.
//
import LocalDB from "@/utils/LocalDB";
import {jsonInitialToUpcase, jsonInitialToLowercase} from "@/utils/utils";
import router from "@/router/index.js"
import {ElNotification} from 'element-plus'

// fetch 请求
export default function fetchRequest(config) {
    return new Promise(resolve => {
        const {url, method, headers, params, data, responseBlob, responseType, upload} = config;
        // 完整url路径
        const fullUrl = getUrl(url) + "?" + getQuery(params);
        const initObject = {
            method,
            mode: "cors",
            cache: "no-cache",
            credentials: "same-origin",
            headers: getHeaders(headers, upload),
            redirect: "follow",
            referrerPolicy: "no-referrer",
            body: getBody(config),
        };
        const autoResponse = responseBlob ? onBlobResponse : onResponse;
        fetch(fullUrl, initObject).then(autoResponse).then(res => {
            if (responseBlob) return res;
            res.data = jsonInitialToLowercase(res.data);
            return res;
        }).then(res => {
            return resolve(decodeResponse(res, responseBlob));
        }).catch(res => {
            if (responseBlob) return resolve(res);
            return resolve(onError(res))
        });
    });
}

/* before */

// 组装 url
export function getUrl(path = "") {
    if (path.indexOf("http://") > -1 || path.indexOf("https://") > -1) {
        return path;
    }
    return window.$config.baseUrl + path;
}

// 组装 query
export function getQuery(params) {
    params = jsonInitialToUpcase(params)
    let queryArray = [];
    for (let key in params) {
        const value = params[key];
        if (value != undefined) {
            queryArray.push(key + "=" + value);
        }
    }
    const query = queryArray.join("&");
    return query;
}

// 组装请求头
export function getHeaders(params, upload) {
    const headers = {
        ...params,
    };
    if (!upload) {
        headers["Content-Type"] = "application/json";
    }
    const token = LocalDB.getItem("token");
    const xToken = LocalDB.getItem("x_token");
    if (token.data) {
        headers["Authorization"] = token.data;
    }
    if (xToken.data) {
        headers["X-Authorization"] = xToken.data;
    }
    return headers;
}

// 处理请求体
export function getBody({method, data, upload}) {
    if (upload) {
        return data;
    }
    if (method == "get" || method == "GET") {
        return undefined;
    }
    data = jsonInitialToUpcase(data)
    return JSON.stringify(data);
}

/* after */

// 处理 blob 文件响应
export async function onBlobResponse(res) {
    if (res.ok) {
        res.data = await res.blob();
        return res;
    }
    throw new Error(JSON.stringify({code: res.status, message: res.statusText}));
}

// 处理正常的 json 响应
export async function onResponse(res) {
    if (res.ok) {
        res.data = await res.json();
        return res;
    }
    throw new Error(JSON.stringify({code: res.status, message: res.statusText}));
}

// 处理错误
export function onError(e) {
    const {$message} = window;
    let err;
    try {
        err = JSON.parse(e.message);
        console.log(err)

    } catch (eq) {
        err = {};
        console.log(eq)
        $message.error("网络错误");
    }

    if (err.code === 401) {
        LocalDB.removeItem("token");
        LocalDB.removeItem("x_token");
        //window.location.reload();
        toLogin()
    } else if (err.code === 403) {
        ElNotification({
            title: '缺少权限',
            message: '您缺少当前功能中的权限，请联系您的上级领导或相关管理员为您配置权限',
            type: 'warning',
        })
    } else {
        $message.error(` ${err.message}`);
    }
    return {
        code: err.code,
        success: false,
        message: err.message,
    };
}

// 解码响应实体
export async function decodeResponse(response, responseBlob) {
    // responseBlob
    if (responseBlob) {
        const blobJson = await blobToJson(response.data);
        if (blobJson.succeeded) {
            return response;
        } else {
            response.data = blobJson;
        }
    }
    const res = encodeResponseForServerObject(response);
    const code = res.data.code;
    const {$message} = window;
    if (res.data.success) {
        const {headers} = res;
        const hasAccessToken = headers.has("access-token");
        if (hasAccessToken) {
            LocalDB.setItem("token", `Bearer ${headers.get("access-token")}`);
            LocalDB.setItem("token_bigscreen", `Bearer ${headers.get("access-token")}`);
        }
        if (headers.has("x-access-token")) {
            LocalDB.setItem("x_token", `Bearer ${headers.get("x-access-token")}`);
            LocalDB.setItem("x_token_bigscreen", `Bearer ${headers.get("x-access-token")}`);
        }
        return res.data;
    }

    if (code === 401) {
        //$message.error("401错误，请重新登录");
        LocalDB.removeItem("token");
        LocalDB.removeItem("x_token");
        //window.location.reload();
        toLogin()
    } else if (code === 403) {
        ElNotification({
            title: '缺少权限',
            message: '您缺少当前功能中的权限，请联系您的上级领导或相关管理员为您配置权限',
            type: 'warning',
        })
        return res.data;
    } else {
        if (res.data.message) {
            $message.error(res.data.message);
        } else {
            console.danger("接口错误", "接口未返回具体错误信息")
        }
        return res.data;
    }
}

// 尝试将 blob 文件转为 json 实体
function blobToJson(data) {
    return new Promise((resolve, reject) => {
        let reader = new FileReader();
        reader.readAsText(data, "utf-8");
        reader.onload = function () {
            try {
                resolve(JSON.parse(reader.result));
            } catch (error) {
                resolve({
                    succeeded: true,
                });
            }
        };
    });
}

// 解析服务器响应数据
function encodeResponseForServerObject(res = {data: {}}) {
    const message = encodeErrorMessage(res.data.errors);
    const newObj = {
        code: res.data.statusCode,
        message: message,
        data: res.data.data,
        success: res.data.succeeded,
    };
    res.data = newObj;
    return res;
}

// 解析服务器响应的错误信息
function encodeErrorMessage(message) {
    let result = "";
    if (Array.isArray(message)) {
        const errs = message.map(err => {
            return (err.messages || [])[0] || "";
        });
        result = errs.join(", ");
    }
    if (typeof message == "object") {
        for (const k in message) {
            const value = message[k];
            result += encodeErrorMessage(value) + " ";
        }
    }
    if (typeof message == "string") {
        result = message;
    }
    return result;
}

function toLogin() {
    console.log("window.location", window.location.hash)
    LocalDB.setItem("redirect", window.location.hash.replace("#", ""))

    setTimeout(() => {
        router.replace("/login")
        //window.location.href = window.location.origin
    }, 300)
}

